/**
*   FuzzyEngine - an Simple flex framework 
*   Copyright (C) 2010 Constantin Aldea
*
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package main.com.sibilla.gadgets
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.utils.getDefinitionByName;
	
	import main.com.sibilla.enums.GadgetsEnum;
	import main.com.sibilla.events.DownloadEvent;
	import main.com.sibilla.gadgets.views.DownloadGadgetView;
	import main.com.sibilla.interfaces.IContext;
	import main.com.sibilla.interfaces.IDownload;
	
	import mx.managers.PopUpManager;
	
	/**
	 * 
	 * @author reborn
	 * La classe DownloadGadget e una classe singleton, un varieta di singleton
	 * che viene usata per fare download di file.
	 * La classe implemente l'interfaccia IDownload con il metodo download
	 * es: 
	 * registra il plugin con il sistema flex
	 * <code>
	 * Gadgets.getInstance().registerGadget(GadgetsEnum.IDOWNLOADER, DownloadGadget);
	 * </code>
	 * per facilita estrarre l'istanza e chiamare metodo download
	 * <code>
		var downloadGadget:IDownload = Gadgets.getInstance().getGadget(GadgetsEnum.IDOWNLOADER) as DownloadGadget;
		downloadGadget.download(this, Albero.MODULE_NAME, Albero.SERVIZIODOWNLOAD, input);
	 * </code>
	 */	
	public class DownloadGadget  implements IDownload
	{

		
		private static var instance:IDownload;
		
		[Exclude(name="DownloadGadget", kind="method")] 
		public function DownloadGadget(){
			
			if(DownloadGadget.instance != null){
				throw new Error("Questa classe e un singleton, usare getInstance");
			}
		
		}
		

		public static function getInstance():IDownload
    	{
	        if (!instance)
	        {
	            try
				{
					
					Gadgets.getInstance().registerGadget(GadgetsEnum.DOWNLOADER, Class(getDefinitionByName(GadgetsEnum.DOWNLOADER)));
					instance = Gadgets.getInstance().getGadget(GadgetsEnum.IDOWNLOADER) as DownloadGadget;
				}catch(e:Error)
				{
					instance = new DownloadGadget();
					
				}
	        }
        
        	return instance;
    	}
		/**
		 * setter per il nome del file da salvare 
		 */		
		private var _filename:String="file.csv";
		/**
		 * setter per l'url del file da scaricare
		 */		
		private var _fullUrl:String;
		
		/**
		 * setter per l'eventuale input 
		 */		
		private var _input:Object;
		
		/**
		 * setter per la sezione modulo edma da chiamare quando l'url viene creato dal sistema
		 */		
		private var _module:String;
		/**
		 * setter servizio da chiamare 
		 */		
		private var _service:String;
		/**
		 * url base 
		 */		
		private var _url:String;
		
	
		private var downloadView:DownloadGadgetView;
        
        private var fr:FileReference;

        
        private  function beginDownload(e:Event):void {
            var request:URLRequest = new URLRequest();
            request.url = fullUrl;
            request.method = URLRequestMethod.POST;
            
            if(input != null){
            	if(input != "") request.data = input;
            }
            
            fr.download(request, filename);
        }

        
        private  function cancelDownload(event:DownloadEvent):void {
            fr.cancel();
            downloadView.downloadProgress.label = "DOWNLOAD ANULLATO";
            PopUpManager.removePopUp(downloadView);
          
        }
		
		
		/**
		 * 
		 * @param parent generalment this, o la componente displayobject che conterra la finestra di conferma
		 * @param context se si usa un indirizzo di url diretto
		 * @param rawModule generalment this, o la componente displayobject che conterra la finestra di conferma
		 * @param rawService se si usa un indirizzo di url diretto
		 * @param rawinput  l'input di un eventuale servizio che server il file
		 * @param rawfilename il nome del filename (si puo chiamare anche tramite il setter del gadget
		 * @param directurl l'ulr diretto se non e uno costruito
		 * <code>
		 *  
		 *  Prima registrare all'inizio o prima di usare il gadget
		 * 	Gadgets.getInstance().registerGadget(GadgetsEnum.IDOWNLOADER, DownloadGadget);
			
			var downloadGadget:DownloadGadget = Gadgets.getInstance().getGadget(GadgetsEnum.IDOWNLOADER) as DownloadGadget;
			downloadGadget.filename = "richieste.csv";
			downloadGadget.download(Application.application as DisplayObject, AppModelLocator.getInstance(), Richiesta.MODULE_NAME, Richiesta.ESPORTA_RICHIESTE);	
						
	 	* </code>
		 */		
		 //, _module:String, _service:String, filename_:String=null, _input:*=null,  directurl:String=null
		public  function download(parent:DisplayObject, context:IContext, rawModule:String, rawService:String, rawinput:*=null, rawfilename:String=null,  directurl:String=null):void{
			if(directurl != null) fullUrl = directurl;
			downloadView = new DownloadGadgetView;
			// set filename
			if(rawfilename != null){
					filename = rawfilename;
			} 
		   	// set input
		   	if(rawinput != null) input = rawinput;
		   	
		   	init();
		   	
		   
		   	service = rawService;
		   	module = rawModule;
		   	if(context !=null)  fullUrl = 	context.url_Fuzzy + "/" + module + "/" + service;
		   	//
		   	downloadView.addEventListener(DownloadEvent.DOWNLOAD, beginDownload);
			downloadView.addEventListener(DownloadEvent.CANCEL_DOWNLOAD, cancelDownload);
			
			PopUpManager.addPopUp(downloadView, parent, true);
			PopUpManager.centerPopUp(downloadView);				
		}

		public function get filename():String
		{
			return _filename;
		}

		public function set filename(val:String):void
		{
			_filename = val;
		}

		public function get fullUrl():String
		{
			return _fullUrl;
		}

		public function set fullUrl(val:String):void
		{
			_fullUrl = val;
		}
		
		
        private function init():void {
            fr = new FileReference();
            
            fr.addEventListener(Event.OPEN, openHandler);
            fr.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            fr.addEventListener(Event.COMPLETE, completeHandler);
        }

		public function get input():Object
		{
			return _input;
		}

		public function set input(val:Object):void
		{
			_input = val;
		}

		public function get module():String
		{
			return _module;
		}
    	
    	

		public function set module(val:String):void
		{
			_module = val;
		}

		public function get service():String
		{
			return _service;
		}
		public function set service(val:String):void
		{
			_service = val;
		}

		public function get url():String
		{
			return _url;
		}
   
		public function set url(val:String):void
		{
			_url = val;
		}

        /**
         * Once the download has completed, change the progress bar's label and 
         * disable the "Cancel" button since the download is already completed.
         */
        private function completeHandler(event:Event):void {
            downloadView.downloadProgress.label = "DOWNLOAD COMPLETO";
           // downloadView.downloadProgress.setProgress(0, 100);
            downloadView.anullaDownload.label = "Chiudi";
           
          //  PopUpManager.removePopUp(downloadView);
            
             
        }

        /**
         * When the OPEN event has dispatched, change the progress bar's label 
         * and enable the "Cancel" button, which allows the user to abort the 
         * download operation.
         */
        private function openHandler(event:Event):void {
            //downloadView.downloadProgress.label = "DOWNLOAD %3%%";
           //downloadView.cancelDownload.enabled = true;
            //btn.enabled = true;
        }
        
        /**
         * While the file is downloading, update the progress bar's status and label.
         */
        private function progressHandler(event:ProgressEvent):void {
        	downloadView.downloadProgress.label = event.bytesLoaded + " di "+ event.bytesTotal;
            downloadView.downloadProgress.setProgress(event.bytesLoaded, event.bytesTotal);
           	trace(event.bytesLoaded + " "+ event.bytesTotal);
           	
           
        }
        // Define reference to the download ProgressBar component.
        // Define reference to the "Cancel" button which will immediately stop the download in progress.
	}
}